package promote.brozen.netty.echo;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.Setter;

/**
 * @author Brozen
 * @date 2020/9/27 3:51 PM
 * @email brozen@qq.com
 */
public class NettyEchoChannelReader extends ChannelInboundHandlerAdapter {

    @Setter
    private boolean echo;

    @Setter
    private String role;

    public NettyEchoChannelReader() {
        this(true, "Server");
    }

    public NettyEchoChannelReader(boolean echo, String role) {
        this.echo = echo;
        this.role = role;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        // 读取数据
        ByteBuf buffer = (ByteBuf) msg;
        byte[] data = new byte[buffer.readableBytes()];
        buffer.readBytes(data);

        // 打印接收的数据
        String msgStr = new String(data);
        System.out.println(role + "Receive: " + msgStr);

        // 返回数据
        if (echo) {
            msgStr = "Echo-> " + msgStr;
            ByteBuf sendBuffer = Unpooled.copiedBuffer(msgStr.getBytes());
            ctx.write(sendBuffer);
            ctx.channel().flush();
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 为了防止频繁唤醒Selector进行消息发送，Netty的write方法并不直接将消息写入底层channel，而是先写入发送缓冲区，
        // 数据达到一定数量或调用flush方法时才会发送到SocketChannel中
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        System.out.println("客户端 Registered：" + ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
        System.out.println("客户端 Unregistered：" + ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        System.out.println("客户端 Active：" + ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        System.out.println("客户端 Inactive：" + ctx);
    }
}
